home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / Multisampler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  14.2 KB  |  413 lines  |  [TEXT/KAHL]

  1. /* Multisampler.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "Multisampler.h"
  31. #include "Memory.h"
  32. #include "SampleSelector.h"
  33. #include "SampleObject.h"
  34. #include "AlgoSampObject.h"
  35. #include "WaveTableObject.h"
  36. #include "AlgoWaveTableObject.h"
  37.  
  38.  
  39. typedef struct OneSampleRec
  40.     {
  41.         /* this is the data reference.  for wave tables, it is an array of waves, so */
  42.         /* we have to dispose it.  for samples, it is the actual wave, so we don't */
  43.         /* dispose it. */
  44.         void*                                    DataReference;
  45.         /* if this is a wave table, then this number contains the number of */
  46.         /* frames per table */
  47.         long                                    NumTables;
  48.         long                                    FramesPerTable;
  49.         /* if this is a sample, then this contains special information about it */
  50.         NumBitsType                        NumBits;
  51.         NumChannelsType                NumChannelsForSample;
  52.         long                                    NumSampleFrames;
  53.         long                                    Loop1Start;
  54.         long                                    Loop1End;
  55.         long                                    Loop2Start;
  56.         long                                    Loop2End;
  57.         long                                    Loop3Start;
  58.         long                                    Loop3End;
  59.         long                                    Origin;
  60.         double                                NaturalFreq;
  61.         long                                    SamplingRate;
  62.  
  63.         /* this is the lowest frequency that the sample should be played at */
  64.         float                                    MinFrequency;
  65.         /* this is the frequency just above the highest frequency that this */
  66.         /* sample should be played at. */
  67.         float                                    MaxFrequency;
  68.  
  69.         /* reference to the next one */
  70.         struct OneSampleRec*    Next;
  71.     } OneSampleRec;
  72.  
  73.  
  74. struct MultiSampleRec
  75.     {
  76.         /* this is the list of samples */
  77.         OneSampleRec*                    SampleList;
  78.  
  79.         /* this flag is True if it was a wave table (i.e. dispose data references) or */
  80.         /* False if it was a sample */
  81.         MyBoolean                            DisposeReferencesFlag;
  82.     };
  83.  
  84.  
  85. /* create a new multisampling object based on a list of wave tables */
  86. /* the named references in the Selector should have been resolved, but it is */
  87. /* the parser's job to do that. */
  88. MultiSampleRec*                NewMultisampleWaveTable(struct SampleSelectorRec* Selector)
  89.     {
  90.         MultiSampleRec*            Multisample;
  91.         OneSampleRec*                ListTail;
  92.         long                                Limit;
  93.         long                                Scan;
  94.  
  95.         CheckPtrExistence(Selector);
  96.  
  97.         Multisample = (MultiSampleRec*)AllocPtrCanFail(sizeof(MultiSampleRec),
  98.             "MultiSampleRec:  wave table variant");
  99.         if (Multisample == NIL)
  100.             {
  101.              FailurePoint1:
  102.                 return NIL;
  103.             }
  104.         Multisample->SampleList = NIL;
  105.         Multisample->DisposeReferencesFlag = True; /* since it's a wave table one */
  106.  
  107.         ListTail = NIL;
  108.         Limit = GetSampleSelectorListLength(Selector);
  109.         for (Scan = 0; Scan < Limit; Scan += 1)
  110.             {
  111.                 OneSampleRec*                NewNode;
  112.  
  113.                 NewNode = (OneSampleRec*)AllocPtrCanFail(sizeof(OneSampleRec),"OneSampleRec");
  114.                 if (NewNode == NIL)
  115.                     {
  116.                      FailurePoint2:
  117.                         while (Multisample->SampleList != NIL)
  118.                             {
  119.                                 NewNode = Multisample->SampleList;
  120.                                 Multisample->SampleList = Multisample->SampleList->Next;
  121.                                 ReleasePtr((char*)NewNode->DataReference);
  122.                                 ReleasePtr((char*)NewNode);
  123.                             }
  124.                         ReleasePtr((char*)Multisample);
  125.                         goto FailurePoint1;
  126.                     }
  127.  
  128.                 NewNode->MinFrequency = GetSampleListEntryLowFreqBound(Selector,Scan);
  129.                 NewNode->MaxFrequency = GetSampleListEntryHighFreqBound(Selector,Scan);
  130.  
  131.                 switch (GetSampleListWaveType(Selector,Scan))
  132.                     {
  133.                         default:
  134.                             EXECUTE(PRERR(ForceAbort,
  135.                                 "NewMultisampleWaveTable:  bad value from GetSampleListWaveType"));
  136.                             break;
  137.                         case eDataWaveTable:
  138.                             {
  139.                                 WaveTableObjectRec*            Table;
  140.                                 long                                        Index;
  141.                                 long                                        NumTables;
  142.  
  143.                                 Table = (WaveTableObjectRec*)GetSampleListWaveReference(Selector,Scan);
  144.                                 CheckPtrExistence(Table);
  145.                                 NumTables = WaveTableObjectGetNumTables(Table);
  146.                                 NewNode->DataReference = AllocPtrCanFail(sizeof(void*) * NumTables,
  147.                                     "Multisample wave table list");
  148.                                 if (NewNode->DataReference == NIL)
  149.                                     {
  150.                                      FailurePoint2a:
  151.                                         ReleasePtr((char*)NewNode);
  152.                                         goto FailurePoint2;
  153.                                     }
  154.                                 for (Index = 0; Index < NumTables; Index += 1)
  155.                                     {
  156.                                         PRNGCHK(NewNode->DataReference,&(((void**)(NewNode->DataReference))[
  157.                                             Index]),sizeof(((void**)(NewNode->DataReference))[Index]));
  158.                                         ((void**)(NewNode->DataReference))[Index]
  159.                                             = WaveTableObjectGetRawSlice(Table,Index);
  160.                                     }
  161.                                 NewNode->FramesPerTable = WaveTableObjectEntriesPerTable(Table);
  162.                                 NewNode->NumTables = NumTables;
  163.                                 NewNode->NumBits = WaveTableObjectGetNumBits(Table);
  164.                             }
  165.                             break;
  166.                         case eAlgoWaveTable:
  167.                             {
  168.                                 AlgoWaveTableObjectRec*    Table;
  169.                                 long                                        Index;
  170.                                 long                                        NumTables;
  171.  
  172.                                 Table = (AlgoWaveTableObjectRec*)GetSampleListWaveReference(
  173.                                     Selector,Scan);
  174.                                 CheckPtrExistence(Table);
  175.                                 NumTables = AlgoWaveTableObjectGetNumTables(Table);
  176.                                 NewNode->DataReference = AllocPtrCanFail(sizeof(void*) * NumTables,
  177.                                     "Multisample wave table list");
  178.                                 if (NewNode->DataReference == NIL)
  179.                                     {
  180.                                         goto FailurePoint2a;
  181.                                     }
  182.                                 for (Index = 0; Index < NumTables; Index += 1)
  183.                                     {
  184.                                         PRNGCHK(NewNode->DataReference,&(((void**)(NewNode->DataReference))[
  185.                                             Index]),sizeof(((void**)(NewNode->DataReference))[Index]));
  186.                                         ((void**)(NewNode->DataReference))[Index]
  187.                                             = AlgoWaveTableObjectGetRawSlice(Table,Index);
  188.                                     }
  189.                                 NewNode->FramesPerTable = AlgoWaveTableObjectGetNumFrames(Table);
  190.                                 NewNode->NumTables = NumTables;
  191.                                 NewNode->NumBits = AlgoWaveTableObjectGetNumBits(Table);
  192.                             }
  193.                             break;
  194.                     }
  195.  
  196.                 NewNode->Next = NIL;
  197.                 if (ListTail != NIL)
  198.                     {
  199.                         ListTail->Next = NewNode;
  200.                     }
  201.                  else
  202.                     {
  203.                         Multisample->SampleList = NewNode;
  204.                     }
  205.                 ListTail = NewNode;
  206.             }
  207.  
  208.         return Multisample;
  209.     }
  210.  
  211.  
  212. /* create a new multisampling object based on a list of samples */
  213. /* the named references in the Selector should have been resolved, but it is */
  214. /* the parser's job to do that. */
  215. MultiSampleRec*                NewMultisampleSample(struct SampleSelectorRec* Selector)
  216.     {
  217.         MultiSampleRec*            Multisample;
  218.         OneSampleRec*                ListTail;
  219.         long                                Limit;
  220.         long                                Scan;
  221.  
  222.         CheckPtrExistence(Selector);
  223.  
  224.         Multisample = (MultiSampleRec*)AllocPtrCanFail(sizeof(MultiSampleRec),
  225.             "MultiSampleRec:  sample variant");
  226.         if (Multisample == NIL)
  227.             {
  228.              FailurePoint1:
  229.                 return NIL;
  230.             }
  231.         Multisample->SampleList = NIL;
  232.         Multisample->DisposeReferencesFlag = False; /* since it's a sample one */
  233.  
  234.         ListTail = NIL;
  235.         Limit = GetSampleSelectorListLength(Selector);
  236.         for (Scan = 0; Scan < Limit; Scan += 1)
  237.             {
  238.                 OneSampleRec*                NewNode;
  239.  
  240.                 NewNode = (OneSampleRec*)AllocPtrCanFail(sizeof(OneSampleRec),"OneSampleRec");
  241.                 if (NewNode == NIL)
  242.                     {
  243.                      FailurePoint2:
  244.                         while (Multisample->SampleList != NIL)
  245.                             {
  246.                                 NewNode = Multisample->SampleList;
  247.                                 Multisample->SampleList = Multisample->SampleList->Next;
  248.                                 ReleasePtr((char*)NewNode->DataReference);
  249.                                 ReleasePtr((char*)NewNode);
  250.                             }
  251.                         ReleasePtr((char*)Multisample);
  252.                         goto FailurePoint1;
  253.                     }
  254.  
  255.                 NewNode->MinFrequency = GetSampleListEntryLowFreqBound(Selector,Scan);
  256.                 NewNode->MaxFrequency = GetSampleListEntryHighFreqBound(Selector,Scan);
  257.  
  258.                 switch (GetSampleListWaveType(Selector,Scan))
  259.                     {
  260.                         default:
  261.                             EXECUTE(PRERR(ForceAbort,
  262.                                 "NewMultisampleSample:  bad value from GetSampleListWaveType"));
  263.                             break;
  264.                         case eDataSample:
  265.                             {
  266.                                 SampleObjectRec*                Sample;
  267.  
  268.                                 Sample = (SampleObjectRec*)GetSampleListWaveReference(Selector,Scan);
  269.                                 CheckPtrExistence(Sample);
  270.                                 NewNode->DataReference = SampleObjectGetRawData(Sample);
  271.                                 NewNode->NumBits = SampleObjectGetNumBits(Sample);
  272.                                 NewNode->NumChannelsForSample = SampleObjectGetNumChannels(Sample);
  273.                                 NewNode->NumSampleFrames = SampleObjectGetNumSampleFrames(Sample);
  274.                                 NewNode->Loop1Start = SampleObjectGetLoopStart1(Sample);
  275.                                 NewNode->Loop1End = SampleObjectGetLoopEnd1(Sample);
  276.                                 NewNode->Loop2Start = SampleObjectGetLoopStart2(Sample);
  277.                                 NewNode->Loop2End = SampleObjectGetLoopEnd2(Sample);
  278.                                 NewNode->Loop3Start = SampleObjectGetLoopStart3(Sample);
  279.                                 NewNode->Loop3End = SampleObjectGetLoopEnd3(Sample);
  280.                                 NewNode->Origin = SampleObjectGetOrigin(Sample);
  281.                                 NewNode->NaturalFreq = SampleObjectGetNaturalFrequency(Sample);
  282.                                 NewNode->SamplingRate = SampleObjectGetSamplingRate(Sample);
  283.                             }
  284.                             break;
  285.                         case eAlgoSample:
  286.                             {
  287.                                 AlgoSampObjectRec*            Sample;
  288.  
  289.                                 Sample = (AlgoSampObjectRec*)GetSampleListWaveReference(Selector,Scan);
  290.                                 CheckPtrExistence(Sample);
  291.                                 NewNode->DataReference = AlgoSampObjectGetRawData(Sample);
  292.                                 NewNode->NumBits = AlgoSampObjectGetNumBits(Sample);
  293.                                 NewNode->NumChannelsForSample = AlgoSampObjectGetNumChannels(Sample);
  294.                                 NewNode->NumSampleFrames = AlgoSampObjetGetNumFrames(Sample);
  295.                                 NewNode->Loop1Start = AlgoSampObjectGetLoopStart1(Sample);
  296.                                 NewNode->Loop1End = AlgoSampObjectGetLoopEnd1(Sample);
  297.                                 NewNode->Loop2Start = AlgoSampObjectGetLoopStart2(Sample);
  298.                                 NewNode->Loop2End = AlgoSampObjectGetLoopEnd2(Sample);
  299.                                 NewNode->Loop3Start = AlgoSampObjectGetLoopStart3(Sample);
  300.                                 NewNode->Loop3End = AlgoSampObjectGetLoopEnd3(Sample);
  301.                                 NewNode->Origin = AlgoSampObjectGetOrigin(Sample);
  302.                                 NewNode->NaturalFreq = AlgoSampObjectGetNaturalFrequency(Sample);
  303.                                 NewNode->SamplingRate = AlgoSampObjectGetSamplingRate(Sample);
  304.                             }
  305.                             break;
  306.                     }
  307.  
  308.                 NewNode->Next = NIL;
  309.                 if (ListTail != NIL)
  310.                     {
  311.                         ListTail->Next = NewNode;
  312.                     }
  313.                  else
  314.                     {
  315.                         Multisample->SampleList = NewNode;
  316.                     }
  317.                 ListTail = NewNode;
  318.             }
  319.  
  320.         return Multisample;
  321.     }
  322.  
  323.  
  324. /* dispose of a multisampling object */
  325. void                                    DisposeMultisample(MultiSampleRec* Multisample)
  326.     {
  327.         CheckPtrExistence(Multisample);
  328.         while (Multisample->SampleList != NIL)
  329.             {
  330.                 OneSampleRec*                Temp;
  331.  
  332.                 Temp = Multisample->SampleList;
  333.                 Multisample->SampleList = Multisample->SampleList->Next;
  334.                 if (Multisample->DisposeReferencesFlag)
  335.                     {
  336.                         ReleasePtr((char*)Temp->DataReference);
  337.                     }
  338.                 ReleasePtr((char*)Temp);
  339.             }
  340.         ReleasePtr((char*)Multisample);
  341.     }
  342.  
  343.  
  344. /* obtain a data reference & info for a wave table.  returns False if there is */
  345. /* no wave table corresponding to the supplied frequency */
  346. MyBoolean                            GetMultisampleReferenceWaveTable(MultiSampleRec* Multisample,
  347.                                                 float FrequencyHertz, void*** TwoDimensionalVecOut,
  348.                                                 long* NumFramesOut, long* NumTablesOut,
  349.                                                 NumBitsType* NumBitsOut)
  350.     {
  351.         OneSampleRec*                Scan;
  352.  
  353.         CheckPtrExistence(Multisample);
  354.         ERROR(!Multisample->DisposeReferencesFlag,PRERR(ForceAbort,
  355.             "GetMultisampleReferenceWaveTable:  list is for samples, not wave tables"));
  356.         Scan = Multisample->SampleList;
  357.         while (Scan != NIL)
  358.             {
  359.                 if ((FrequencyHertz >= Scan->MinFrequency)
  360.                     && (FrequencyHertz < Scan->MaxFrequency))
  361.                     {
  362.                         *TwoDimensionalVecOut = (void**)(Scan->DataReference);
  363.                         *NumFramesOut = Scan->FramesPerTable;
  364.                         *NumTablesOut = Scan->NumTables;
  365.                         *NumBitsOut = Scan->NumBits;
  366.                         return True;
  367.                     }
  368.                 Scan = Scan->Next;
  369.             }
  370.         return False;
  371.     }
  372.  
  373.  
  374. /* obtain a data reference & info for a sample.  returns False if there is no */
  375. /* sample corresponding to the supplied frequency. */
  376. MyBoolean                            GetMultisampleReferenceSample(MultiSampleRec* Multisample,
  377.                                                 float FrequencyHertz, void** DataOut, long* NumFramesOut,
  378.                                                 NumBitsType* NumBitsOut, NumChannelsType* NumChannelsOut,
  379.                                                 long* Loop1StartOut, long* Loop1EndOut, long* Loop2StartOut,
  380.                                                 long* Loop2EndOut, long* Loop3StartOut, long* Loop3EndOut,
  381.                                                 long* OriginOut, double* NaturalFreqOut, long* SamplingRateOut)
  382.     {
  383.         OneSampleRec*                Scan;
  384.  
  385.         CheckPtrExistence(Multisample);
  386.         ERROR(Multisample->DisposeReferencesFlag,PRERR(ForceAbort,
  387.             "GetMultisampleReferenceSample:  list is for wave tables, not samples"));
  388.         Scan = Multisample->SampleList;
  389.         while (Scan != NIL)
  390.             {
  391.                 if ((FrequencyHertz >= Scan->MinFrequency)
  392.                     && (FrequencyHertz < Scan->MaxFrequency))
  393.                     {
  394.                         *DataOut = Scan->DataReference;
  395.                         *NumFramesOut = Scan->NumSampleFrames;
  396.                         *NumBitsOut = Scan->NumBits;
  397.                         *NumChannelsOut = Scan->NumChannelsForSample;
  398.                         *Loop1StartOut = Scan->Loop1Start;
  399.                         *Loop1EndOut = Scan->Loop1End;
  400.                         *Loop2StartOut = Scan->Loop2Start;
  401.                         *Loop2EndOut = Scan->Loop2End;
  402.                         *Loop3StartOut = Scan->Loop3Start;
  403.                         *Loop3EndOut = Scan->Loop3End;
  404.                         *OriginOut = Scan->Origin;
  405.                         *NaturalFreqOut = Scan->NaturalFreq;
  406.                         *SamplingRateOut = Scan->SamplingRate;
  407.                         return True;
  408.                     }
  409.                 Scan = Scan->Next;
  410.             }
  411.         return False;
  412.     }
  413.